<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
  <title>CFTagLib - CF Tag Library Planning</title>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

  <style type="text/css">
  #g_title p, #g_footer p, #g_description p {
    margin: 0;
  }
  /*

  	-- -- -- -- -- -- --
  	Browser Fixes
  	-- -- -- -- -- -- --
  	
  	This file uses CSS filtering methods to fix various
  	layout bugs.

  	Each of the following three imported files is a 
  	separate, browser-specific CSS file that keeps all 
  	hacks out of the main style sheet.
  	
  	Over time, as supporting these browsers no longer
  	remains a priority, cleaning up the hacks is as
  	easy as deleting the @import statement below, or
  	simply no longer linking this file from the HTML.
  	
  */

  /* 
    fix ie6 "peekaboo bug" using the "holly hack". 
    Note, this style only gets applied to ie6
  */
  * html .wrapper {
    height: 0.1%;
  }

  /* 
   * IE5 mac - overrides the IE/Win hack 
   */

  /*\*//*/

  * html #threecolumn div {
  	height: auto;
  }

  /**/


  /* 
   * IE5/Win-specific CSS -ensures #container wraps all content on window resize
   */

  @media tty {
   i{content:"\";/*" "*/}} * html #container { height: 1%; } /*";}
  }/* */
  /* Styling for editable elements. Eventually, this will be part of the style. */
  .editable {
    border: 1px dashed blue;
  }
  
  #footer {
    clear: both;
  }
  
  /* Extra divs hidden by default. The custom CSS can override this though */
  #extraDiv1, #extraDiv2, #extraDiv3, #extraDiv4, #extraDiv5, #extraDiv6 {
    display: none;
  }
  
  a img,:link img,:visited img {border: none;}


  /*
    -- -- -- -- -- -- --
    1 Column Layout
    -- -- -- -- -- -- --
  */

  /* Center #container, constrain to 718px width
  ----------------------------------------------- */
  body {
    text-align: center;
  }
  #container {
    width: 718px;
    text-align: left;
    margin: 0 auto;
  }

  #main-content {
    overflow: hidden;
  }

  /** BEGIN CUSTOM SKIN **/
  /* general layout */

  body {
    font-family: Lucida Grande, Lucida Sans Unicode, Verdana, Helvetica, Arial, sans-serif;
    font-size: 83%;
    margin: 0em;
    padding: 0em;
    border-top: 1em solid #e2e6ec;
    background: #e2e6ec url(container-fill.gif) center repeat-y;
  }
  body div#container {
    padding: 0em;
    margin-top: 0em;
    border-top: 1px solid #e2e6ec; /* a hack: without it Firefox adds top margin in layouts with sidebar */
    background: url(container-top.gif) top no-repeat;
  }
  div#container div.wrapper {
    padding: 0em;
    margin: 0em;
  }
  div#header {
    padding: 0em 35px;
    padding-top: 2em;
    padding-bottom: 2em;
    _padding-bottom: 1em; /* hack for IE6 */
    margin: 0em;
    margin-top: 2em;
    background: url(header-fill.gif) repeat-y;
  }
  div#header div.wrapper {
    padding: 0em;
    margin: 0em;
  }
  div#main-content {
    line-height: 160%;
    color: #3f3f3f;
    background: url(content-top.gif) top no-repeat;
  }
  div#sidebar,div#sidebar-alternate {
    font-size: 83%;
    line-height: 140%;
    color: #3f3f3f;
    background: url(content-top.gif) top no-repeat;
    padding: 0em;
    margin: 0em;
    padding-top: 1.5em;
  }
  div#footer {
    margin-top: 2em;
    background: url(content-top.gif) top no-repeat;
    padding: 1em 35px;
    color: #7f7f7f;
  }
  div#footer hr { /* I don't like this, but I have no idea why that <hr> is there */
    display: none;
  }

  /* adjusting widths for different layouts */

  body#onecolumn div#main-content {
    padding: 0em 35px;
    width: 648px;
  }
  body#twocolumn-right div#main-content {
    padding: 0em 25px;
    width: 420px;
    margin-left: 10px;
  }
  body#twocolumn-left div#main-content {
    padding: 0em 25px;
    width: 420px;
    margin-right: 8px;
    display: inline;
  }
  body#twocolumn-left div#sidebar {
    padding-left: 15px;
    width: 215px;
  }
  body#twocolumn-right div#sidebar {
    padding-right: 15px;
    width: 215px;
  }
  body#threecolumn div#main-content {
    padding: 0em 25px;
    width: 370px;
  }
  body#threecolumn div#sidebar {
    padding-left: 15px;
    width: 125px;
    margin-left: 10px;
    display: inline;
  }
  body#threecolumn div#sidebar-alternate {
    padding-right: 15px;
    width: 125px;
  }

  /* general styles: headings */

  h1, h2, h3, h4, h5, h6, p.description {
    font-family: Lucida Grande, Lucida Sans Unicode, Verdana, Helvetica, Arial, sans-serif; 
  }
  h1 {
    font-size: 160%;
    font-weight: bold;
    color: black;
    border-bottom: 1px solid #b3e6e6;
    padding-bottom: 0.2em;
    display: inline; /* so that the underline spans only text width, and not the entire page */
    line-height: 400%; /* for padding below, the above line took away other possibilities */
  }
  h2 {
    font-size: 120%;
    font-weight: bold;
    color: black;
    border-bottom: 1px solid #b3e6e6;
    padding-bottom: 0.2em;
    display: inline; /* so that the underline spans only text width, and not the entire page */
    line-height: 400%; /* for padding below, the above line took away other possibilities */
  }
  h3 {
    font-size: 110%;
    font-weight: bold;
    border-bottom: 1px solid #b3e6e6;
    padding-bottom: 0.2em;
    color: black;
    display: inline; /* so that the underline spans only text width, and not the entire page */
    line-height: 300%; /* for padding below, the above line took away other possibilities */
  }
  h4 {
    font-size: 100%;
    font-weight: bold;
    border-bottom: 1px solid #b3e6e6;
    padding-bottom: 0.2em;
    color: black;
    display: inline; /* so that the underline spans only text width, and not the entire page */
    line-height: 200%; /* for padding below, the above line took away other possibilities */
  }
  h5 {
    font-size: 100%;
    font-weight: bold;
    color: black;
    display: inline;
  }
  h6 {
    font-size: 100%;
    font-weight: normal;
    color: black;
    display: inline;
  }
  hr {
    background: white;
    height: 1px;
    border: 0em;
    border-top: 1px solid #b3e6e6;
    margin: 1em 0em;
  }

  /* general styles: links */

  a {
    color: #125ebc;
    text-decoration: none;
    border-bottom: 1px solid #125ebc; /* this underline is further away from the text = more legibility */
  }
  a:visited {
    color: #638bbc;
    text-decoration: none;
    border-bottom: 1px solid #638bbc; /* this underline is further away from the text = more legibility */
  }

  /* general styles: lists */

  ul, ol {
    margin-left: 1.8em;
    padding: 0em;
  }
  dt {
    margin-left: 1.8em;
  }
  blockquote {
    margin-left: 1.8em;
  }

  /* general styles: tables */

  table {
    border-collapse: collapse;
    margin-top: 1em;
    margin-bottom: 1em;
    margin-left: -0.6em;
    margin-right: -0.6em;
  }

  table td,table th {
    padding: 0.3em 0.6em;
    vertical-align: top;
    text-align: left;
  }
  table th {
    border-bottom: 1px solid #b3e6e6;
  }
  table caption {
    text-align: left;
    font-weight: bold;
    color: #4FBBBB;
    padding: 0em;
    _padding: 0em 0.6em; /* hack for IE6: it understands padding differently here */
  }

  /* specific styles */

  h1#page-title {
    font-size: 220%;
    font-weight: normal;
    color: #125ebc;
    letter-spacing: -1px;
    display: block;
    border: 0em;
    padding: 0em;
    margin: 0em;
    line-height: 100%;
  }
  div#g_description {
    font-size: 140%;
    font-weight: normal;
    color: #125ebc; 
  }

  /* correcting horizontal margins for different layouts */

  body#twocolumn-left div#header, body#threecolumn div#header {
    padding-left: 25px;
  }

  /** END CUSTOM SKIN **/
  </style>

  <!-- Hack to avoid flash of unstyled content in IE -->
  

<script language="JavaScript">
<!--

function SymError()
{
  return true;
}

window.onerror = SymError;

var SymRealWinOpen = window.open;

function SymWinOpen(url, name, attributes)
{
  return (new Object());
}

window.open = SymWinOpen;

//-->
</script>

<script> </script>
</head>

<body id="onecolumn">
  <div id="container">
    <div class="wrapper">
      <div id="header">
        <div class="wrapper">
          <h1 id="page-title"><div id='g_title'><p>Why CFTagLib?</p></div></h1>

          <div style="clear: both;"></div>
          <p class="description"><div id='g_description'>&nbsp;</div></p>
          <div style="clear: both"></div>
        </div>
      </div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="start.html">Next &raquo;</a>
      <!-- /editable --><!-- /wrapper --><!-- /header -->
      <div id="main-content">
        <div class="wrapper">
          <div class="content-item"><div id='g_body'><p></p> 
<h3>Is There a Need for CfTagLib?</h3> 
<link href="style.css" rel="stylesheet">
<br/>
Coldfusion is known for rapid application development.  It already has <em>cfform</em>, <em>cfinput</em>, <em>cfselect</em>, and <em>cftextarea</em>.  So why do we have the needs to create another version of them?  Well, tags in our CfTagLib are lightweight, designed for specific needs, but flexible enough for you to create your own theme/layout and even add additional attributes to meet your needs.  They address different concerns than the built-in tags do.
<p>
Where I work, deadlines are often yesterday.  The bugs in the presentation layer are often minus and tedious.  Most of the times they are not even bugs, just consistency and 508 related issues.  CfTagLib aims to prevent these problems and saves us time in development and debugging.  Here is a simple example of creating and modifying a user account.  To create a form for both <em>new</em> and <em>edit</em> views, this is what you would write:
</p>
These queries are used to populate the state and country select lists.
<p class="pre">
&lt;cfquery datasource="dsn" name="qryState"&gt;<br/>
<span class="tab1">SELECT STATE_CD, STATE_NM FROM STATE ORDER BY STATE_NM ASC</span>
&lt;/cfquery&gt;<br/>
<br/>
&lt;cfquery datasource="dsn" name="qryCountry"&gt;<br/>
<span class="tab1">SELECT COUNTRY_CD, COUNTRY_NM FROM COUNTRY ORDER BY COUNTRY_NM ASC</span>
&lt;/cfquery&gt;<br/>
</p>
<br/>
This needs to be on the <em>edit</em> page.  If these variables do not already exist, then they take the values of the <em>qryAccount</em> query.  These variables would already exist if the form returns after validation failed.
<p class="pre">
&lt;cfset account="Edit"/&gt;<br/>
&lt;cfif structKeyExists(variables,'qryAccount')&gt;<br/>
<span class="tab1">	&lt;cfparam name="attribubtes.id" default="#trim(qryAccount.id)#"/&gt;</span>
<span class="tab1">	&lt;cfparam name="attribubtes.firstName" default="#trim(qryAccount.firstName)#"/&gt;</span>
<span class="tab1">	&lt;cfparam name="attribubtes.lastName" default="#trim(qryAccount.lastName)#"/&gt;</span>
<span class="tab1">	&lt;cfparam name="attribubtes.email" default="#trim(qryAccount.email)#"/&gt;</span>
<span class="tab1">	&lt;cfparam name="attribubtes.state" default="#trim(qryAccount.state_cd)#"/&gt;</span>
<span class="tab1">	&lt;cfparam name="attribubtes.country" default="#trim(qryAccount.country_cd)#"/&gt;</span>
&lt;/cfif&gt;
</p>
<br/>
For the <em>new</em> page, this is necessary.
<p class="pre">
&lt;cfset account="New"/&gt;<br/>
&lt;cfparam name="attribubtes.id" default="0"/&gt;<br/>
&lt;cfparam name="attribubtes.firstName" default=""/&gt;<br/>
&lt;cfparam name="attribubtes.lastName" default=""/&gt;<br/>
&lt;cfparam name="attribubtes.email" default=""/&gt;<br/>
&lt;cfparam name="attribubtes.state" default=""/&gt;<br/>
&lt;cfparam name="attribubtes.country" default=""/&gt;<br/>
</p>
<br/>
Here is the form.
<p class="pre">
&lt;cfoutput&gt;<br/>
<span class="tab1">	 &lt;form id="account" action="#myself##xfa.action#&amp;id=#attributes.id#" method="post"&gt;</span>
<span class="tab2">	 &lt;fieldset&gt;&lt;legend class="legend"&gt;#account# Account&lt;/legend&gt;</span><br/>
<span class="tab3">		&lt;label class="label" for="firstName"&gt;First Name&lt;/label&gt;</span>
<span class="tab3">				&lt;input type="text" id="firstName" name="firstName" value="#htmlEditFormat(attributes.firstName)#" maxlength="64"/&gt;&lt;br/&gt;</span><br/>
<span class="tab3">			 	&lt;label class="label" for="lastName"&gt;Last Name&lt;/label&gt;</span>
<span class="tab3">				&lt;input type="text" id="lastName" name="lastName" value="#htmlEditFormat(attributes.lastName)#" maxlength="64"/&gt;&lt;br/&gt;</span><br/>
<span class="tab3">			 	&lt;label class="label" for="email"&gt;Email Address&lt;/label&gt;</span>
<span class="tab3">				&lt;input type="text" id="email" name="email" value="#htmlEditFormat(attributes.email)#" maxlength="64"/&gt;&lt;br/&gt;</span><br/>
<span class="tab3">			 	&lt;label class="label" for="state"&gt;State&lt;/label&gt;</span>
<span class="tab3">				&lt;select id="state" name="state"&gt;</span>
<span class="tab4">					&lt;option value=""&gt;Select One...&lt;/option&gt;</span>
<span class="tab4">					&lt;cfloop query="qryState"&gt;</span>
<span class="tab5">						&lt;option value="#trim(qryState.state_cd)#"&lt;cfif trim(qryState.state_cd) eq trim(attributes.state)&gt;selected&lt;/cfif&gt;&gt;#qryState.state_nm#&lt;/option&gt;</span>
<span class="tab4">					&lt;/cfloop&gt;</span>
<span class="tab3">				&lt;/select&gt;&lt;br/&gt;</span><br/>
<span class="tab3">			 	&lt;label class="label" for="country"&gt;Country&lt;/label&gt;</span>
<span class="tab3">				&lt;select id="country" name="country"&gt;</span>
<span class="tab4">					&lt;option value=""&gt;Select One...&lt;/option&gt;</span>
<span class="tab4">					&lt;cfloop query="qryCountry"&gt;</span>
<span class="tab5">						&lt;option value="#trim(qryCountry.country_cd)#"&lt;cfif trim(qryCountry.country_cd) eq trim(attributes.country)&gt;selected&lt;/cfif&gt;&gt;#qryState.state_nm#&lt;/option&gt;</span>
<span class="tab4">					&lt;/cfloop&gt;</span>
<span class="tab3">				&lt;/select&gt;&lt;br/&gt;</span><br/>
<span class="tab3">				&lt;button type="submit"&gt;Submit&lt;/button&gt;</span>
<span class="tab2">				&lt;/fieldset&gt;</span>
<span class="tab1">	 &lt;/form&gt;</span>
&lt;/cfoutput&gt;
</p>

Now if you use our CfTagLib, this is equivalent to everything written above.
<p class="pre">
&lt;!---Set these on <em>new</em> page---&gt;<br/>
&lt;cfset account="New"/&gt;<br/>
&lt;cfset action="create"/&gt;<br/><br/>
&lt;!---Set these on <em>edit</em> page---&gt;<br/>
&lt;cfset account="Edit"/&gt;<br/>
&lt;cfset action="Modify"/&gt;<br/>
<br/>
&lt;cfset request.ui.form.all.config.dsn = "dsn"/&gt;<br/>
&lt;cfset request.ui.form.select.config.optionHeader = "Select One..."/&gt;<br/>
<br/>
&lt;cfimport taglib="/taglib/fusebox/" prefix="ui"/&gt;<br/>
<br/>
&lt;cfoutput&gt;<br/>
<span class="tab1">&lt;ui:form legend="#account# Account" name="#action#"&gt;</span>
<span class="tab2">&lt;ui:hidden name="qryAccount.id" default="0"/&gt;</span><br/>
<span class="tab2">&lt;ui:input name="qryAccount.firstName" label="First Name"/&gt;</span><br/>
<span class="tab2">&lt;ui:input name="qryAccount.lastName" label="Last Name"/&gt;</span><br/>
<span class="tab2">&lt;ui:input name="qryAccount.email" label="Email Address"/&gt;</span><br/>
<span class="tab2">&lt;ui:select table="state" value="state_cd" option="state_nm" checkValue="qryAccount.state_cd"/&gt;</span><br/>
<span class="tab2">&lt;ui:select table="country" value="country_cd" option="country_nm" checkValue="qryAccount.country_cd"/&gt;</span>
<span class="tab1">&lt;/ui:form&gt;</span>
&lt;/cfoutput&gt;
</p>

With this code you can be sure that all the labels have the <em>for</em> attribute that matches the <em>id</em> attribute in the form fields.  All text fields have <em>htmlEditFormat()</em> wrap around it, and all fields have <em>trim()</em>.
</div></div>

          <div style="clear: both"></div>
        </div>
      </div>
      <!-- /wrapper --><!-- /main-content -->
      <div id="footer"><div class="wrapper">
        <hr /><a href="start.html">Next &raquo;</a>
        <p><div id='g_footer'>&nbsp;</div></p>
        <div style="clear: both"></div>
      </div></div>

      <!-- /wrapper --><!-- /footer -->
    </div>
  </div>
<!-- /wrapper --><!-- /container -->

<div id="extraDiv1"><span></span></div><div id="extraDiv2"><span></span></div>
<div id="extraDiv3"><span></span></div><div id="extraDiv4"><span></span></div>
<div id="extraDiv5"><span></span></div><div id="extraDiv6"><span></span></div>

</body>
</html>

<script language="JavaScript">
<!--
var SymRealOnLoad;
var SymRealOnUnload;

function SymOnUnload()
{
  window.open = SymWinOpen;
  if(SymRealOnUnload != null)
     SymRealOnUnload();
}

function SymOnLoad()
{
  if(SymRealOnLoad != null)
     SymRealOnLoad();
  window.open = SymRealWinOpen;
  SymRealOnUnload = window.onunload;
  window.onunload = SymOnUnload;
}

SymRealOnLoad = window.onload;
window.onload = SymOnLoad;

//-->
</script>

